package com.example.act6.study.controller;

import cn.hutool.core.util.StrUtil;
import com.example.act6.common.entities.CommonResult;
import com.example.act6.study.service.ActivitiDefineService;
import com.example.act6.study.service.IActReProcdefService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * @return {@link null}
 * @Author jrw
 * @Description 流程定义相关
 * @Date 2022/3/7 15:19
 * @Param
 **/
@RestController
@RequestMapping("/define")
public class ActivitiDefineController {

    @Autowired
    private ActivitiDefineService activitiDefineService;

    @Autowired
    private IActReProcdefService iActReProcdefService;

    @Autowired
    private ProcessEngine processEngine;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private RuntimeService runtimeService;

    @GetMapping("")
    public String hi() {

        return iActReProcdefService.list().toString();
    }

    /**
     * @return {@link CommonResult}
     * @Author jrw
     * @Description 文件形式部署
     * @Date 2022/3/7 16:25
     * @Param [file]
     **/
    @PostMapping("/deploy")
    public CommonResult deploy(MultipartFile file) {
        String exportDir = this.getClass().getResource("/").getPath();
        String fileName = file.getOriginalFilename();

        if (StringUtils.isBlank(fileName)) {
            return CommonResult.error("请选择要部署的流程文件");
        }
        return CommonResult.ok(activitiDefineService.deploy(exportDir, file));
    }

    /**
     * 分页查询部署列表
     *
     * @param params 查询参数
     */
    @GetMapping("/list")
    public CommonResult list(@RequestParam Map<String, Object> params) {
        return CommonResult.ok(activitiDefineService.queryPage(params));
    }

    /**
     * 查看流程图
     *
     * @return ResultDTO
     */
    @GetMapping("/viewProcessImage")
    public void viewProcessImage(String processDefinitionId, HttpServletResponse response) {
        activitiDefineService.viewProcessImage(processDefinitionId, response);
    }

    /**
     * 转为模型
     *
     * @param processDefinitionId
     * @return ResultDTO
     */
    @GetMapping("/convertToModel")
    public CommonResult convertToModel(String processDefinitionId) {
        return activitiDefineService.convertToModel(processDefinitionId);
    }

    /**
     * @return {@link null}
     * @Author jrw
     * @Description 启动流程实例
     * @Date 2022/3/8 17:10
     * @Param
     **/
    @GetMapping("/startProcessInstanceById")
    public CommonResult startProcessInstanceById(String processDefinitionId, String assignee) {
        if (StrUtil.isEmpty(processDefinitionId) || StrUtil.isEmpty(assignee)) {
            return CommonResult.error("实例Id或者代理人不能为空");
        }
        return activitiDefineService.startProcessInstanceById(processDefinitionId, assignee);
    }

    /**
     * 激活 / 挂起
     *
     * @param state
     * @param processDefinitionId
     * @return
     */
    @RequestMapping("/update")
    public CommonResult update(int state, String processDefinitionId) {
        return activitiDefineService.updateState(state, processDefinitionId);
    }

    /**
     * 删除部署的流程，级联删除流程实例
     *
     * @param deploymentId 流程部署标识
     * @return ResultDTO
     */
    @PostMapping("/delete")
    public CommonResult delete(String deploymentId, Boolean cascade) {
        return activitiDefineService.deleteBatch(deploymentId, cascade);
    }

    /**
     * @return {@link CommonResult}
     * @Author jrw
     * @Description 获取所有流程实例
     * @Date 2022/3/9 13:38
     * @Param [processInstanceId]
     **/
    @GetMapping("/getProcessInstanceList")
    public CommonResult getProcessInstanceStatus() {
        List<Map<String, Object>> mapList = new ArrayList<>();
        for (ProcessInstance processInstance : processEngine.getRuntimeService().createProcessInstanceQuery().list()) {
            Map<String, Object> map = new HashMap<>();
            if (processInstance != null) {
                Date startTime = processInstance.getStartTime();
                String deploymentId = processInstance.getDeploymentId();
                String processDefinitionId = processInstance.getProcessDefinitionId();
                String description = processInstance.getDescription();
                String name = processInstance.getName();
                String tenantId = processInstance.getTenantId();
                String businessKey = processInstance.getBusinessKey();
                Map<String, Object> processVariables = processInstance.getProcessVariables();
                String id = processInstance.getId();
                map.put("processInstanceId", id);
                map.put("startTime", startTime);
                map.put("deploymentId", deploymentId);
                map.put("processDefinitionId", processDefinitionId);
                map.put("description", description);
                map.put("name", name);
                map.put("tenantId", tenantId);
                map.put("businessKey", businessKey);
                map.put("message", "流程进行中");
            } else {
                map.put("message", "流程已结束");
            }
            mapList.add(map);
        }
        return CommonResult.ok(mapList);
    }


    @GetMapping("/delProcessInstance")
    public CommonResult getProcessInstanceStatus(String processInstanceId, String deleteReason) {
        ProcessInstance processInstance = processEngine.getRuntimeService().createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        String id = processInstance.getId();
        runtimeService.deleteProcessInstance(id, deleteReason);
        return CommonResult.ok();
    }

    /**
     * @return {@link CommonResult}
     * @Author jrw
     * @Description 获取流程定义信息
     * @Date 2022/3/9 13:50
     * @Param [processDefinitionId]
     **/
    @GetMapping("/getProcessDefinition")
    public CommonResult getProcessDefinition(String processDefinitionId) {

        List<Map<String, Object>> maps = new ArrayList<>();
        List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().list();
        for (ProcessDefinition processDefinition : list) {
            Map<String, Object> map = new HashMap<>();

            String deploymentId = processDefinition.getDeploymentId();
            String id = processDefinition.getId();
            String description = processDefinition.getDescription();
            String name = processDefinition.getName();
            String category = processDefinition.getCategory();
            int version = processDefinition.getVersion();

            map.put("deploymentId", deploymentId);
            map.put("id", id);
            map.put("description", description);
            map.put("name", name);
            map.put("category", category);
            map.put("version", version);
            maps.add(map);
        }
        return CommonResult.ok(maps);
    }
}
